/***********************************************************************************
 * 文件名： pid_static.h
 * 作者： 	刘言
 * 版本： 	2
 * 说明：
 * 		PID算法计算器，静态时现（单例模式），一个项目中需要用到多组PID参数请使用面向对
 * 	象设计的pid.c。
 * 		PID 计算方法： 控制（输出）值的变化量 = 
 * 				  比例系数 * 偏差值 
 * 				+ 积分系数 * 偏差累加值 
 * 				+ 微分系数 * (偏差值 - 上一个偏差值)
 * 		
 * 修改记录：
 * 	20201106: 初版
 *  20220622: 预处理计算确定最合适的变量类型。
***********************************************************************************/
#ifndef _PID_STATIC_H_
#define _PID_STATIC_H_

#ifdef __cplusplus
 extern "C" {
#endif 

#include "pid_static_config.h"
#include "polsys.h"

#ifdef _PID_USE_FLOAT
	typedef float input_value_t;
	typedef float ctrl_value_t;
	typedef float inte_value_t;
#else
	#define _PID_CTRL_MAX	((_PID_KP * _PID_INPUT_MAX + _PID_KI * _PID_MAX_INTE_VALUE + _PID_KD * (_PID_INPUT_MAX - 0)) / _PID_SCALE)

	#if (_PID_MAX_INTE_VALUE >= (-(_PID_MIN_INTE_VALUE)))
		#define _PID_INTE_MAX _PID_MAX_INTE_VALUE
	#else
		#define _PID_INTE_MAX (-(_PID_MIN_INTE_VALUE))
	#endif

	#if (_PID_INPUT_MAX <= 0X7F)
		typedef s8 input_value_t;
	#elif (_PID_INPUT_MAX <= 0X7FFF)
		typedef s16 input_value_t;
	#elif (_PID_INPUT_MAX <= 0X7FFFFFFF)
		typedef s32 input_value_t;
	#else
		#error "被控量（输入量）这么大就太不应该了。"
	#endif

	#if (_PID_CTRL_MAX <= 0X7F)
		typedef s8 ctrl_value_t;
	#elif (_PID_CTRL_MAX <= 0X7FFF)
		typedef s16 ctrl_value_t;
	#elif (_PID_CTRL_MAX <= 0X7FFFFFFF)
		typedef s32 ctrl_value_t;
	#else
		#error "参数设置的不合理导致控制量过大。"
	#endif

	#if (_PID_INTE_MAX <= 0X7F)
		typedef s8 inte_value_t;
	#elif (_PID_INTE_MAX <= 0X7FFF)
		typedef s16 inte_value_t;
	#elif (_PID_INTE_MAX <= 0X7FFFFFFF)
		typedef s32 inte_value_t;
	#else
		#error "偏差累加值（积分）上下限设置的不合理。"
	#endif
#endif


// 获取控制（输出）量的变化量。
// 获取的值只是PID算法按照参数计算出的变化量，实际可能超出控制器允许最大或者最小值，需要自行处理。
// target - 目标值
// real - 实际值
// 返回值：控制量的变化量
ctrl_value_t PID_GetChange(input_value_t target, input_value_t real);

void PID_Init();



#ifdef __cplusplus
}
#endif 

#endif
